在上一篇我們的測試程式如下
<?php
namespace Recca0120\Ithome30\Tests;
use Mockery;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use PHPUnit\Framework\TestCase;
use Recca0120\Ithome30\PttCrawler;
use Psr\Http\Client\ClientInterface;
class PttCrawlerTest extends TestCase
{
public function test_fetch_board_page()
{
/** @var Mockery\Mock|ClientInterface $httpClient */
$httpClient = Mockery::mock(ClientInterface::class);
$httpClient
->allows('sendRequest')
->andReturn(new Response(200, [], file_get_contents(__DIR__ . '/fixtures/ptt_home.html')));
$crawler = new PttCrawler($httpClient);
$records = $crawler->all();
self::assertEquals([
'name' => 'Gossiping',
"nuser" => '12185',
'class' => '綜合',
'title' => '[八卦]不停重複今日公祭明日忘記',
], $records[0]);
}
}
這樣的測試程式其實是不夠好的,因為我們從測試程式碼只看得出
但還有一個也很重要的資訊網址
我們並沒有驗證到啊。但網址又在 PttCrawler 裡,那該怎麼驗證這段程式碼呢?這時我們就可以使用 Mockery::spy
來進行驗證(顧名思意就是放個間諜到程式裡囉),所以我們的測試程式就可以改為
<?php
namespace Recca0120\Ithome30\Tests;
use Mockery;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use PHPUnit\Framework\TestCase;
use Recca0120\Ithome30\PttCrawler;
use Psr\Http\Client\ClientInterface;
class PttCrawlerTest extends TestCase
{
public function test_fetch_board_page()
{
/** @var Mockery\Mock|ClientInterface $httpClient */
// mock 改為 spy
$httpClient = Mockery::spy(ClientInterface::class);
$httpClient
->allows('sendRequest')
->andReturn(new Response(200, [], file_get_contents(__DIR__ . '/fixtures/ptt_home.html')));
$crawler = new PttCrawler($httpClient);
$records = $crawler->all();
self::assertEquals([
'name' => 'Gossiping',
"nuser" => '12185',
'class' => '綜合',
'title' => '[八卦]不停重複今日公祭明日忘記',
], $records[0]);
// 新增驗證
$httpClient->shouldHaveReceived('sendRequest')->once()->with(Mockery::on(function (Request $request) {
return (((string)$request->getUri()) === 'https://www.ptt.cc/bbs/hotboards.html');
}));
}
}
調整完後我們就可以從測試很清楚的看出這隻程式的目的為
https://www.ptt.cc/bbs/hotboards.html
的網頁資料只看測試案例的時候就能大致理解整個程式的輪廓是相當重要的,因為這樣的測試程式幾乎就已經等同於說明書了,並且我們在測試程式裡保留了『完整的原始資訊』,不論任何時候需要重構程式或改寫程式,我們都不必擔心最後寫出的結果會不一致了